在理解了 Wasm 如何執行之後,我們會意外地發現一個可怕的事實,如果 Wasm 應用程式只能在 Sandbox 裡面執行,那要怎麼跟系統互動呢?
傳統的 Container 總會有需要讀寫檔案系統、列印日誌等操作,但 Wasm 是怎麼做到這些事情的呢?
這時候 WASI (WebAssembly System Interface) 就橫空出世了,在這個額外的擴充介面中,定義了許多系統函式(syscall)的呼叫方式,且整個操作是基於能力的安全性,使用者必須顯式聲明哪些權限、檔案、或者能力是允許授權給 Wasm Runtime 來呼叫對應的 WASI 函式。以檔案系統為例,在 Wasm Runtime 內的環境稱為 Guest,反之則稱為 Host,如果沒有聲明「要把 Host 中的資料夾 A 映射到 Guest 中的資料夾 B」,WASI 將沒有辦法存取外部環境的資料夾。這是不是跟 docker
執行時需要聲明檔案系統的映射關係很像呢?
是,也不是。
由於 WASI 現在還在預覽階段,比起原生應用程式所使用的系統函式庫,如:glibc 或 POSIX API 等,都還有一些差距。若應用程式中涵蓋了部分 WASI 尚未定義的系統函式,除了編譯出來的結果無法執行外,更常在編譯當下就直接遇到錯誤,表示某些特定功能在 WASM/WASI 環境中不支援。
例如網路插座(Network Socket)相關的函式便是殘缺的,在標準的 WASI 下,幾乎沒辦法做 Socket 相關的操作,如:資料庫連接器(Database Connector)、Socket Programming 都沒辦法執行。
即使標準沒有定義,但 Network Socket 是剛性需求,有大量的應用都是與此相關,因此各家 Wasm Runtime 百花齊放,都推出自己的額外擴充來支援上述的應用程式。如:WasmEdge_WASI_Sokcet、WASIX 等非正式標準的擴充。
但我相信,在不久的未來,標準會繼續發展,把這些需要額外擴充的功能都收回去,還給開發者們更加友善的環境。